<?php

namespace App\Service\Kms\Home;

use AlibabaCloud\SDK\Dyvmsapi\V20170525\Models\ListHotlineTransferNumberResponseBody\data\values;
use App\Enums\OpenShop\InvestmentPromotion\SignOrderEnum;
use App\Enums\OpenShop\InvestmentPromotion\SiteMissionEnum;
use App\Enums\OpenShop\InvestmentPromotion\UserOrderEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Error\Kms\HomeError;
use App\Exceptions\KfHttpResponseException;
use App\Models\Clickhouse\Guanyuan\GyCloseShopCHModel;
use App\Models\Clickhouse\Guanyuan\GyDailyDeliveryReportCHModel;
use App\Models\Clickhouse\Guanyuan\GyDmDaySalesAnalyseCHModel;
use App\Models\Clickhouse\Guanyuan\GyPreparatoryOverviewCHModel;
use App\Models\Clickhouse\Guanyuan\GyShopCityConsumptionOpeningsCHModel;
use App\Models\Clickhouse\Guanyuan\GyShopSignCHModel;
use App\Models\Clickhouse\KfOrder\KfOrderCHModel;
use App\Models\Clickhouse\KfOrder\KfWaimaiOrderCHModel;
use App\Models\Clickhouse\OrderGoods\DeliveryNoteGoodsCHModel;
use App\Models\Clickhouse\OrderGoods\OrderCHModel;
use App\Models\Common\AmapAreaModel;
use App\Models\Cruise\CruiseCheckSelfDetailModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\Guanyuan\GuanyuanSyncShopBusinessModel;
use App\Models\Kfos\Order\DeliveryNoteGoodsModel;
use App\Models\Kfos\Order\NewOrdersModel;
use App\Models\OpenShop\Common\SiteLocationMallModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopAddressModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrderTagsMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationManageModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationRegionMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSiteMissionModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageMappingModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\Shop\ShopModel;
use App\Service\BaseService;
use App\Service\Kms\Task\UserRoleService;
use App\Service\OpenShop\Organization\WarZoneService;
use Exception;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Tinderbox\Clickhouse\Exceptions\ClientException;
use Tinderbox\ClickhouseBuilder\Query\Enums\Operator;
use Tinderbox\ClickhouseBuilder\Query\JoinClause;

class HomeService extends BaseService
{
    const ACTIVITY_STORE_DAU  = 1;
    const ACTIVITY_STORE_WAU  = 2;
    const ACTIVITY_STORE_MAU  = 3;
    const ACTIVITY_STORE_QAU  = 4;
    const ACTIVITY_STORE_YAU  = 5;
    const ACTIVITY_STORE_TEXT = [
        self::ACTIVITY_STORE_DAU => "近7天",
        self::ACTIVITY_STORE_WAU => "近7周",
        self::ACTIVITY_STORE_MAU => "近7月",
        self::ACTIVITY_STORE_QAU => "7个季度",
        self::ACTIVITY_STORE_YAU => "所有年",
    ];

    const REVENUE_SITUATION_TYPE_TODAY     = 1;
    const REVENUE_SITUATION_TYPE_YESTERDAY = 2;
    const REVENUE_SITUATION_TYPE_WEEK      = 3;
    const REVENUE_SITUATION_TYPE_MONTH     = 4;
    const REVENUE_SITUATION_TYPE_CUSTOM    = 5;
    const REVENUE_SITUATION_TYPE_TEXT      = [
        self::REVENUE_SITUATION_TYPE_TODAY     => "今天",
        self::REVENUE_SITUATION_TYPE_YESTERDAY => "昨天",
        self::REVENUE_SITUATION_TYPE_WEEK      => "本周",
        self::REVENUE_SITUATION_TYPE_MONTH     => "本月",
        self::REVENUE_SITUATION_TYPE_CUSTOM    => "自定义",
    ];

    const REVENUE_SITUATION_COMPARE_TYPE_WEEK  = 1;
    const REVENUE_SITUATION_COMPARE_TYPE_MONTH = 2;
    const REVENUE_SITUATION_COMPARE_TYPE_TEXT  = [
        self::REVENUE_SITUATION_COMPARE_TYPE_WEEK  => "周同比",
        self::REVENUE_SITUATION_COMPARE_TYPE_MONTH => "月同比",
    ];

    const REVENUE_TYPE_1    = 1;
    const REVENUE_TYPE_2    = 2;
    const REVENUE_TYPE_3    = 3;
    const REVENUE_TYPE_TEXT = [
        self::REVENUE_TYPE_1 => "GMV",
        self::REVENUE_TYPE_2 => "实收",
        self::REVENUE_TYPE_3 => "门店订货",
    ];

    const REGION_SELECTION_TYPE_0    = 1;
    const REGION_SELECTION_TYPE_1    = 2;
    const REGION_SELECTION_TYPE_2    = 3;
    const REGION_SELECTION_TYPE_3    = 4;
    const REGION_SELECTION_TYPE_4    = 5;
    const REGION_SELECTION_TYPE_5    = 6;
    const REGION_SELECTION_TYPE_TEXT = [
        self::REGION_SELECTION_TYPE_0 => "全国",
        self::REGION_SELECTION_TYPE_4 => '战区',
        self::REGION_SELECTION_TYPE_1 => "分公司",
        self::REGION_SELECTION_TYPE_2 => "省",
        self::REGION_SELECTION_TYPE_3 => "市",
        self::REGION_SELECTION_TYPE_5 => '区',
    ];

    /**
     * kms - 首页数据展示 - 角色可见区域下拉选择
     * @throws Exception
     */
    public static function regionSelection()
    {

        try {
            $userRole = UserRoleService::getUserRole(auth()->user()->rmsUserId);

            if (!in_array($userRole["role"], [
                UserRoleService::ROLE_SPECIAL_0,
                UserRoleService::ROLE_SPECIAL_1,
                UserRoleService::ROLE_SPECIAL_2,
                UserRoleService::ROLE_BASE_PROVINCE,
                UserRoleService::ROLE_BASE_CITY_MANAGER,
                UserRoleService::ROLE_BASE_DEVELOP_CITY_MANAGER,
                UserRoleService::ROLE_BASE_SUPERVISOR,
                UserRoleService::ROLE_BASE_OBSERVER,
                UserRoleService::ROLE_BASE_WAR_REGION,
            ])) {
                throw new KfHttpResponseException(HomeError::ROLE_HAS_NO_PERMISSION_ACCESS_HOME_PAGE);
            }

            if(
                $userRole["role"] == UserRoleService::ROLE_BASE_WAR_REGION
                ||
                $userRole["homeBranchOffice"]["isHeadOfficeAttachUser"]
            ){
                $selection = self::defaultWarRegionSelection();
            }else{
                $selection = self::defaultProvinceRegionSelection();
            }

            switch ($userRole["role"]) {
                case UserRoleService::ROLE_BASE_WAR_REGION:
                    if (!$userRole["homeBranchOffice"]["isHeadOfficeAttachUser"]) {
                        // ToDo 战区总可见范围获取
                        $selection = collect($selection)
                            ->whereIn(
                                "value",
                                collect($userRole["warZone"])->pluck("id")->toArray()
                            )
                            ->values()
                            ->toArray();
                    }
                    break;
                case UserRoleService::ROLE_BASE_PROVINCE:
                    if (!$userRole["homeBranchOffice"]["isHeadOfficeAttachUser"]) {
                        //省总可见范围获取
                        $selection = collect($selection)
                            ->whereIn(
                                "value",
                                $userRole["homeBranchOffice"]["branchOfficeProvince"]
                            )
                            ->values()
                            ->toArray();
                    }
                    break;
                case UserRoleService::ROLE_BASE_CITY_MANAGER:
                case UserRoleService::ROLE_BASE_DEVELOP_CITY_MANAGER:
                    if (!$userRole["homeBranchOffice"]["isHeadOfficeAttachUser"]) {
                        //省总可见范围获取
                        $provinceSelection =  collect($selection)
                            ->whereIn(
                                "value",
                                $userRole["homeBranchOffice"]["branchOfficeProvince"]
                            )
                            ->values()
                            ->toArray();

                        $selection = collect($provinceSelection[0]["children"] ?? [])
                            ->whereIn("value", $userRole["homeBranchOffice"]["branchOfficeCity"])
                            ->values()
                            ->toArray();
                    }
                    break;
                case UserRoleService::ROLE_BASE_OBSERVER:
                    if (!$userRole["userResponsibleArea"]["all"]) {
                        //省总可见范围获取
                        $selection = collect($selection)
                            ->whereIn(
                                "value",
                                $userRole["homeBranchOffice"]["branchOfficeProvince"]
                            )
                            ->values()
                            ->toArray();
                    }
                    break;
                case UserRoleService::ROLE_BASE_SUPERVISOR:
                    $selection = [];
            }

            return [
                "role"      => $userRole["role"],
                "roleDesc"  => $userRole["desc"],
                "selection" => $selection
            ];

        } catch (Exception $exception) {
            handleKfException($exception);
        }
    }

    /**
     * 默认战区下拉
     *
     * @param int $isDistrict
     * @return mixed
     */
    public static function defaultWarRegionSelection(int $isDistrict = 0)
    {
        $func = function () use ($isDistrict) {
            $aMapArea = AmapAreaModel::query()->get();
            return array_merge(
                [
                    [
                        "label"    => "全国",
                        "value"    => 0,
                        "type"     => self::REGION_SELECTION_TYPE_0,
                        "children" => [],
                    ]
                ],
                WarZoneService::regionTree()->map(function (OpenShopRegionManageModel $regionManageModel) use (
                    $isDistrict,
                    $aMapArea
                ) {
                    $children = [];
                    $regionManageModel->regionMappingRel
                        ->map(function (OpenShopRegionManageMappingModel $manageMappingModel) use (
                            $isDistrict,
                            $aMapArea,
                            &$children
                        ) {
                            return $manageMappingModel->organizationManageRel->regionRel
                                ->map(function (
                                    OpenShopOrganizationRegionMappingModel $regionMappingModel
                                ) use ($isDistrict, $aMapArea, &$children) {
                                    array_push($children, [
                                        'label'    => $regionMappingModel->provinceName,
                                        'value'    => $regionMappingModel->provinceCode,
                                        'type'     => self::REGION_SELECTION_TYPE_2,
                                        'children' => $aMapArea->where('pCode',
                                            $regionMappingModel->provinceCode)
                                                               ->map(function ($area) use($aMapArea,$isDistrict) {
                                                                   if (!$isDistrict) {
                                                                       return [
                                                                           'label' => $area['label'],
                                                                           'value' => $area['code'],
                                                                           'type'  => self::REGION_SELECTION_TYPE_3,
                                                                       ];
                                                                   } else {
                                                                       return [
                                                                           'label'    => $area['label'],
                                                                           'value'    => $area['code'],
                                                                           'type'     => self::REGION_SELECTION_TYPE_3,
                                                                           'children' => $aMapArea->where('pCode', $area['code'])
                                                                               ->map(
                                                                                   function ($isDistrict) {
                                                                                       return [
                                                                                           'label' => $isDistrict['label'],
                                                                                           'value' => $isDistrict['code'],
                                                                                           'type'  => self::REGION_SELECTION_TYPE_5,
                                                                                       ];
                                                                                   }
                                                                               )->values()->toArray()
                                                                       ];
                                                                   }
                                                               })->values()->toArray()
                                    ]);
                                });
                        });


                    return [
                        'label'    => $regionManageModel->name,
                        'value'    => $regionManageModel->id,
                        'type'     => self::REGION_SELECTION_TYPE_4,
                        'children' => $children,
                    ];
                })->values()->toArray()
            );
        };

        return Cache::store("redis")->remember("kms:home:defaultWarRegionSelection:" . $isDistrict, 30 * 60, function () use ($func) {
            return $func();
        });
    }

    /**
     * 默认省区下拉
     *
     * @param int $isDistrict
     * @return mixed
     */
    public static function defaultProvinceRegionSelection(int $isDistrict = 0)
    {
        $func = function() use ($isDistrict) {
            $aMapArea = AmapAreaModel::query()->get();
            $selection = [
                [
                    "label"    => "全国",
                    "value"    => 0,
                    "type"     => self::REGION_SELECTION_TYPE_0,
                    "children" => [],
                ]
            ];
            OpenShopOrganizationManageModel::allOrganizationManage()
                                              ->where("type", "<>",
                                                  OpenShopOrganizationManageModel::HEADQUARTERS_ID)
                                              ->map(function ($item) use ($isDistrict, $aMapArea, &$selection) {
                                                  if ($item->regionRel != null) {
                                                      foreach ($item->regionRel as $val) {
                                                          array_push(
                                                              $selection,
                                                              [
                                                                  'label'    => $val->provinceName,
                                                                  'type'     => self::REGION_SELECTION_TYPE_2,
                                                                  'value'    => $val->provinceCode,
                                                                  'children' => $aMapArea
                                                                      ->where('pCode',
                                                                          $val->provinceCode)
                                                                      ->map(function ($area) use ($aMapArea,$isDistrict) {
                                                                          if (!$isDistrict) {
                                                                              return [
                                                                                  'label' => $area['label'],
                                                                                  'value' => $area['code'],
                                                                                  'type'  => self::REGION_SELECTION_TYPE_3,
                                                                              ];
                                                                          } else {
                                                                              return [
                                                                                  'label'    => $area['label'],
                                                                                  'value'    => $area['code'],
                                                                                  'type'     => self::REGION_SELECTION_TYPE_3,
                                                                                  'children' => $aMapArea->where('pCode', $area['code'])
                                                                                      ->map(
                                                                                          function ($isDistrict) {
                                                                                              return [
                                                                                                  'label' => $isDistrict['label'],
                                                                                                  'value' => $isDistrict['code'],
                                                                                                  'type'  => self::REGION_SELECTION_TYPE_5,
                                                                                              ];
                                                                                          }
                                                                                      )->values()->toArray()
                                                                              ];
                                                                          }
                                                                      })->values()
                                                                      ->toArray()
                                                              ]
                                                          );
                                                      }
                                                  }
                                              });

            return $selection;
        };

        return Cache::store("redis")->remember(
            "kms:home:defaultProvinceRegionSelection:" . $isDistrict,
            30 * 60,
            function () use ($func) {
                return $func();
            }
        );
    }

    /**
     * kms - 首页数据展示 - 门店活跃
     *
     * @param object $params
     * @return array|array[]
     * @throws ClientException
     */
    public static function activityStore(object $params): array
    {
        $start = attributeGet($params, "start", "");
        $end   = attributeGet($params, "end", "");

        $xValues = self::getActivityStoreXValues($params->type, $start, $end);
        $query   = null;
        if ($params->role == UserRoleService::ROLE_BASE_SUPERVISOR) {
            //督导权限
            $signOrder = OpenShopSignOrderModel::query()
                                               ->whereHas("checkAcceptRel",
                                                   function (
                                                       $query
                                                   ) {
                                                       $query->where("managerId",
                                                           auth()->user()->rmsUserId);
                                                   })
                                               ->get();
            if ($signOrder->isNotEmpty()) {
                $query = function ($query) use ($signOrder) {
                    $query->whereIn("storeCode", $signOrder->pluck("shopCode")->toArray());
                };
            } else {
                $query = function ($query) {
                    $query->where("storeCode", 0);
                };
            }
        } else {
            switch ($params->regionSelectionType) {
                case self::REGION_SELECTION_TYPE_1://分公司查询
                    $query = function ($query) use ($params) {
//                        $query->where("region", "LIKE", "%" . str_replace("分公司", "", $params->region) . "%");
                        $organizationModel = OpenShopOrganizationManageModel::query()
                                                                    ->with("regionRel")
                                                                    ->where("name", $params->region)
                                                                    ->first();

                        if($organizationModel && $organizationModel->regionRel){
                            return $query->whereIn("province", $organizationModel->regionRel->pluck("provinceName")->toArray());
                        }else{
                            return $query->where("province", "-1");
                        }
                    };
                    break;
                case self::REGION_SELECTION_TYPE_2://省级查询
                    $query = function ($query) use ($params) {
                        $query->where("province", $params->region);
                    };
                    break;
                case self::REGION_SELECTION_TYPE_3://市级查询
                    $query = function ($query) use ($params) {
                        $query->where("city", $params->region);
                    };
                    break;
                case self::REGION_SELECTION_TYPE_4:// 战区查询
                    $warRegionRow = OpenShopRegionManageModel::query()
                                             ->with([
                                                 "regionMappingRel"     => function ($query) {
                                                     $query->with(["organizationManageRel" => function($query){
                                                         $query->with("regionRel");
                                                     }]);
                                                 }
                                             ])->where("id", $params->regionValue)->first();

                    $provinceNames = [];
                    $warRegionRow->regionMappingRel->each(function (OpenShopRegionManageMappingModel $manageMappingModel) use (&$provinceNames) {
                        $provinceNames = array_merge(
                            $provinceNames,
                            $manageMappingModel->organizationManageRel->regionRel->pluck("provinceName")->toArray()
                        );
                    });

                    if ($provinceNames) {
                         $query = function ($query) use ($provinceNames) {
                            $query->whereIn("province", $provinceNames);
                        };
                    } else {
                        $query = function($query){
                            $query->where("province", "-1");
                        };
                    }
                    break;
            }
        }

        $shopBusinessCHModelCollection = GyDailyDeliveryReportCHModel::query()
                                                                     ->when($query, function ($subQuery) use ($query) {
                                                                         return $subQuery->where($query);
                                                                     })
                                                                     ->where("date", ">=", $xValues["queryStartDate"])
                                                                     ->where("date", "<=", $xValues["queryEndDate"])
                                                                     ->where('storeCode', ">", 0)
                                                                     ->groupBy($xValues["groupByField"])
                                                                     ->select([
                                                                         $xValues["groupByField"] . " as x",
                                                                         raw('count(distinct storeCode) as val')
                                                                     ])
                                                                     ->get();

        return array_merge(
            [
                "list" => collect($xValues["xValues"])->map(function ($xValue) use ($shopBusinessCHModelCollection) {
                    return [
                        "x"   => $xValue,
                        "val" => (string)attributeGet(
                            $shopBusinessCHModelCollection->where("x", $xValue)->first(),
                            "val",
                            0
                        )
                    ];
                })->values()->toArray()
            ],
            collect($xValues)->except(["xValues"])->toArray(),
            ["type" => $params->type]
        );


    }

    /**
     * 获取活跃门店x轴数据
     *
     * @param int $type
     * @param string $start
     * @param string $end
     * @return array
     */
    private static function getActivityStoreXValues(int $type, string $start, string $end): array
    {
        //todo 特殊处理 当前时间大于9点  展示当日数据  否则不展示
        if((int)Carbon::now()->format("Hi") > 900){
            $endCarbon = Carbon::now()->subDay();
        }else{
            $endCarbon = Carbon::now()->subDays(2);
        }
        $xValues = [];
        switch ($type) {
            case self::ACTIVITY_STORE_DAU:
                if (empty($start) || empty($end)) {
                    $initTimestamp = $startTimestamp = Carbon::now()->subDays(7)->startOfDay()->timestamp;
                    $endTimestamp  = $endCarbon->clone()->startOfDay()->timestamp;
                } else {
                    $initTimestamp = $startTimestamp = Carbon::createFromDate($start)->startOfDay()->timestamp;
                    $endTimestamp  = Carbon::createFromDate($end)->startOfDay()->timestamp;
                }
                while ($startTimestamp <= $endTimestamp) {
                    array_push($xValues, Carbon::createFromTimestamp($startTimestamp)->format("Y-m-d"));
                    $startTimestamp = Carbon::createFromTimestamp($startTimestamp)->addDay()->timestamp;
                }
                $groupByField = "dayGroup";
                break;
            case self::ACTIVITY_STORE_WAU:
                if (empty($start) || empty($end)) {
                    $initTimestamp = $startTimestamp = Carbon::now()->subWeeks(7)->startOfWeek()->timestamp;
                    $endTimestamp  = $endCarbon->clone()->endOfWeek()->timestamp;
                } else {
                    $initTimestamp = $startTimestamp = Carbon::createFromDate($start)->startOfWeek()->timestamp;
                    $endTimestamp  = Carbon::createFromDate($end)->endOfWeek()->timestamp;
                }
                while ($startTimestamp <= $endTimestamp) {
                    array_push($xValues, Carbon::createFromTimestamp($startTimestamp)->format("Y-m-d"));
                    $startTimestamp = Carbon::createFromTimestamp($startTimestamp)->addWeek()->timestamp;
                }
                $groupByField = "weekGroup";
                break;
            case self::ACTIVITY_STORE_MAU:
                if (empty($start) || empty($end)) {
                    $initTimestamp = $startTimestamp = Carbon::now()->subMonths(7)->startOfMonth()->timestamp;
                    $endTimestamp  = $endCarbon->clone()->endOfMonth()->timestamp;
                } else {
                    $initTimestamp = $startTimestamp = Carbon::createFromDate($start)->startOfMonth()->timestamp;
                    $endTimestamp  = Carbon::createFromDate($end)->endOfMonth()->timestamp;
                }
                while ($startTimestamp <= $endTimestamp) {
                    array_push($xValues, Carbon::createFromTimestamp($startTimestamp)->format("Y-m"));
                    $startTimestamp = Carbon::createFromTimestamp($startTimestamp)->addMonth()->timestamp;
                }
                $groupByField = "monthGroup";
                break;
            case self::ACTIVITY_STORE_QAU:
                if (empty($start) || empty($end)) {
                    $initTimestamp = $startTimestamp = Carbon::now()->subQuarters(7)->startOfQuarter()->timestamp;
                    $endTimestamp  = $endCarbon->clone()->endOfQuarter()->timestamp;
                } else {
                    $initTimestamp = $startTimestamp = Carbon::createFromDate($start)->startOfQuarter()->timestamp;
                    $endTimestamp  = Carbon::createFromDate($end)->endOfQuarter()->timestamp;
                }
                while ($startTimestamp <= $endTimestamp) {
                    array_push($xValues, Carbon::createFromTimestamp($startTimestamp)->format("Y-m"));
                    $startTimestamp = Carbon::createFromTimestamp($startTimestamp)->addQuarter()->timestamp;
                }
                $groupByField = "quarterGroup";
                break;
            case self::ACTIVITY_STORE_YAU:
                if (empty($start) || empty($end)) {
                    $initTimestamp = $startTimestamp = Carbon::now()->subYears(7)->startOfYear()->timestamp;
                    $endTimestamp  = $endCarbon->clone()->endOfYear()->timestamp;
                } else {
                    $initTimestamp = $startTimestamp = Carbon::createFromDate($start)->startOfYear()->timestamp;
                    $endTimestamp  = Carbon::createFromDate($end)->endOfYear()->timestamp;
                }
                while ($startTimestamp <= $endTimestamp) {
                    array_push($xValues, Carbon::createFromTimestamp($startTimestamp)->format("Y"));
                    $startTimestamp = Carbon::createFromTimestamp($startTimestamp)->addYear()->timestamp;
                }
                $groupByField = "yearGroup";
                break;
        }

        $queryStartDate = Carbon::createFromTimestamp($initTimestamp)->format("Y-m-d");
        $queryEndDate   = Carbon::createFromTimestamp($endTimestamp)->format("Y-m-d");


        return compact("xValues", "queryStartDate", "queryEndDate", "groupByField");
    }

    /**
     * kms - 首页数据展示 - 营收情况
     *
     * @param object $params
     * @return array
     * @throws Exception
     */
    public static function revenueSituation(object $params): array
    {
        $start = attributeGet($params, "start", "");
        $end   = attributeGet($params, "end", "");

        //坐标数据&查询周期
        $parsedCoords = self::revenueSituationXValues($params->type, $params->compareType, $start, $end);

        return array_merge(
            [
                "shopClassification" => self::revenueSituationStoreClassification(
                    $params->role,
                    $parsedCoords,
                    attributeGet($params, "regionSelectionType", -1),
                    attributeGet($params, "region", "")
                )
            ],//门店分级
            [
                "gmv" => self::revenueSituation_1(
                    $params->role,
                    $parsedCoords,
                    attributeGet($params, "regionSelectionType", -1),
                    attributeGet($params, "region", ""),
                    attributeGet($params, "regionValue", "")
                )
            ],//gmv
            [
                "realIncome" => self::revenueSituation_2(
                    $params->role,
                    $parsedCoords,
                    attributeGet($params, "regionSelectionType", -1),
                    attributeGet($params, "region", ""),
                    attributeGet($params, "regionValue", "")
                )
            ],//实收
            [
                "orderGoods" => self::revenueSituation_3(
                    $params->role,
                    $parsedCoords,
                    attributeGet($params, "regionSelectionType", -1),
                    attributeGet($params, "region", ""),
                    attributeGet($params, "regionValue", "")
                )
            ],//订货
            collect($parsedCoords)->except(["xValues", "xCompareValues"])->toArray(),
            (array)$params
        );
    }

    /**
     * 营收情况 - 底部x轴数据集合
     *
     * @param int $type
     * @param int $compareType
     * @param string $start
     * @param string $end
     * @return array
     * @throws Exception
     */
    private static function revenueSituationXValues(int $type, int $compareType, string $start, string $end): array
    {
        $xValues = $xCompareValues = [];
        switch ($type) {
            case self::REVENUE_SITUATION_TYPE_TODAY:
                $endTimestamp   = Carbon::now()->endOfDay()->timestamp;
                $startTimestamp = Carbon::now()->startOfDay()->timestamp;
                break;
            case self::REVENUE_SITUATION_TYPE_YESTERDAY:
                $endTimestamp   = Carbon::yesterday()->endOfDay()->timestamp;
                $startTimestamp = Carbon::yesterday()->startOfDay()->timestamp;
                break;
            case self::REVENUE_SITUATION_TYPE_WEEK:
                $endTimestamp   = Carbon::now()->endOfDay()->timestamp;
                $startTimestamp = Carbon::now()->startOfWeek()->timestamp;
                break;
            case self::REVENUE_SITUATION_TYPE_MONTH:
                $endTimestamp   = Carbon::now()->endOfDay()->timestamp;
                $startTimestamp = Carbon::now()->startOfMonth()->timestamp;
                break;
            case self::REVENUE_SITUATION_TYPE_CUSTOM:
                $endTimestamp   = Carbon::parse($end)->endOfDay()->timestamp;
                $startTimestamp = Carbon::parse($start)->startOfDay()->timestamp;
                break;
            default:
                throw new Exception("参数 type 异常 {$type}");
        }

//        $groupType      = (($endTimestamp - $startTimestamp) > 24 * 60 * 60) ? "d" : "h";
        $groupType      = "d";
        $queryStartDate = Carbon::createFromTimestamp($startTimestamp)->format("Y-m-d");
        $queryEndDate   = Carbon::createFromTimestamp($endTimestamp)->format("Y-m-d");

        while ($startTimestamp <= $endTimestamp) {
            $dt = Carbon::createFromTimestamp($startTimestamp);
            switch ($groupType) {
                case "h":
                    array_push($xValues, $dt->copy()->format("H:s"));
                    switch ($compareType) {
                        case self::REVENUE_SITUATION_COMPARE_TYPE_WEEK:
                            array_push($xCompareValues, $dt->copy()->subWeek()->format("H:s"));
                            break;
                        case self::REVENUE_SITUATION_COMPARE_TYPE_MONTH:
                            array_push($xCompareValues, $dt->copy()->subMonth()->format("H:s"));
                            break;
                    }
                    $startTimestamp = $dt->copy()->addHours(4)->timestamp;
                    break;
                case "d":
                    array_push($xValues, $dt->copy()->format("Y-m-d"));
                    switch ($compareType) {
                        case self::REVENUE_SITUATION_COMPARE_TYPE_WEEK:
                            array_push($xCompareValues, $dt->copy()->subWeek()->format("Y-m-d"));
                            break;
                        case self::REVENUE_SITUATION_COMPARE_TYPE_MONTH:
                            array_push($xCompareValues, $dt->copy()->subMonth()->format("Y-m-d"));
                            break;
                    }
                    $startTimestamp = $dt->copy()->addDay()->timestamp;
                    break;
            }

        }

        switch ($compareType) {
            case self::REVENUE_SITUATION_COMPARE_TYPE_WEEK:
                $compareQueryStartDate = Carbon::createFromDate($queryStartDate)->subWeek()->format("Y-m-d");
                $compareQueryEndDate   = Carbon::createFromDate($queryEndDate)->subWeek()->format("Y-m-d");
                break;
            case self::REVENUE_SITUATION_COMPARE_TYPE_MONTH:
                $compareQueryStartDate = Carbon::createFromDate($queryStartDate)->subMonth()->format("Y-m-d");
                $compareQueryEndDate   = Carbon::createFromDate($queryEndDate)->subMonth()->format("Y-m-d");
                break;
        }

        return compact(
            "queryStartDate",
            "queryEndDate",
            "compareQueryStartDate",
            "compareQueryEndDate",
            "xValues",
            "xCompareValues",
            "groupType"
        );
    }

    /**
     * @param int $role
     * @param array $parsedCoords
     * @param int $regionSelectionType
     * @param string $region
     * @return array
     * @throws ClientException
     */
    public static function revenueSituationStoreClassification(
        int $role,
        array $parsedCoords,
        int $regionSelectionType,
        string $region
    ): array {
        if ($parsedCoords["queryEndDate"] == Carbon::now()->format("Y-m-d")) {
            $date = Carbon::now()->subDay()->format("Y-m-d");
        } else {
            $date = $parsedCoords["queryEndDate"];
        }
        $gyDailyDeliveryReportCHModel = GyDailyDeliveryReportCHModel::buildHomeSearchQuery(
            $role, $regionSelectionType, $region
        )->where(
            "date", $date
        )->groupBy(
            "storeClassification"
        )->select(
            ["storeClassification as x", raw("count(*) as val")]
        )->get();

        $sumVal = $gyDailyDeliveryReportCHModel->pluck("val")->sum();

        return collect([
            "明星",
            "金牛",
            "瘦狗",
            "问题",
            "ST"
        ])->map(function ($x) use ($gyDailyDeliveryReportCHModel, $sumVal) {
            $val = attributeGet($gyDailyDeliveryReportCHModel->where("x", $x)->first(), "val", 0);
            return [
                "x"    => $x,
                "val"  => $val,
                "rate" => $sumVal ? ((string)(round(bcdiv($val, $sumVal, 4), 2) * 100)) . "%" : "-"
            ];
        })->values()->toArray();
    }

    /**
     * 营收情况 - gmv
     *
     * @param int $role
     * @param array $parsedCoords
     * @param int $regionSelectionType
     * @param string $region
     * @param string $regionValue
     * @return array[]
     * @throws ClientException
     */
    private static function revenueSituation_1(
        int $role,
        array $parsedCoords,
        int $regionSelectionType,
        string $region,
        string $regionValue
    ): array {
        if ($parsedCoords["groupType"] == "d") {
            if (
                $parsedCoords["queryEndDate"] == $parsedCoords["queryStartDate"]
                &&
                $parsedCoords["queryStartDate"] == Carbon::now()->format("Y-m-d")
            ) {
                //当天gmv取夸父收银
                $total              = KfOrderCHModel::buildHomeSearchQuery(
                    $role, $regionSelectionType, $region, $regionValue
                )->where(
                    "completeTime", ">=", Carbon::now()->startOfDay()->timestamp
                )->select([raw('sum(originalPrice) as total')])->first();
                $businessCollection = collect([
                    [
                        "x"   => $parsedCoords["queryEndDate"],
                        "val" => bcdiv100(($total["total"] ?? 0))
                    ]
                ]);
            } else {
                //选中日期 gmv
                $businessCollection = GyDailyDeliveryReportCHModel::buildHomeSearchQuery(
                    $role, $regionSelectionType, $region
                )->where("date", ">=", $parsedCoords["queryStartDate"]
                )->where("date", "<=", $parsedCoords["queryEndDate"]
                )->groupBy("date"
                )->select(["date as x", raw("sum(orderTurnover) as val")]
                )->get();
            }


            //选中日期同比 gmv
            $compareBusinessCollection = GyDailyDeliveryReportCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region
            )->where("date", ">=", $parsedCoords["compareQueryStartDate"]
            )->where("date", "<=", $parsedCoords["compareQueryEndDate"]
            )->groupBy("date"
            )->select(["date as x", raw("sum(orderTurnover) as val")]
            )->get();

            $list = collect($parsedCoords["xValues"])
                ->map(function ($xValue) use ($businessCollection) {
                    return [
                        "x"   => $xValue,
                        "val" => (string)(attributeGet(
                                $businessCollection->where("x", $xValue)->first(),
                                "val",
                                0
                            ) * 100)
                    ];
                })->values();

            $comparedList = collect($parsedCoords["xCompareValues"])
                ->map(function ($xValue) use ($compareBusinessCollection) {
                    return [
                        "x"   => $xValue,
                        "val" => (string)(attributeGet(
                                $compareBusinessCollection->where("x", $xValue)->first(),
                                "val",
                                0
                            ) * 100)
                    ];
                })->values();

            $listSum         = $list->pluck("val")->sum();
            $comparedListSum = $comparedList->pluck("val")->sum();
        } else {
            //当天门店堂食订单时间段聚合订单数据
            $kfOrderCHModel = KfOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["queryStartDate"]}')")
            )->select([
                    raw('sum(originalPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfOrderCHModel $kfOrderCHModel) {
                return [
                    "total" => $kfOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfOrderCHModel->hour)->format("H")
                ];
            })->values();

            //当天门店外卖订单时间段聚合订单数据
            $kfWmOrderCHModel = KfWaimaiOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["queryStartDate"]}')")
            )->select([
                    raw('sum(originalPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfWaimaiOrderCHModel $kfWaimaiOrderCHModel) {
                return [
                    "total" => $kfWaimaiOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfWaimaiOrderCHModel->hour)->format("H")
                ];
            })->values();

            //同比当天门店堂食订单时间段聚合订单数据
            $compareKfOrderCHModel = KfOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["compareQueryStartDate"]}')")
            )->select([
                    raw('sum(originalPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfOrderCHModel $kfOrderCHModel) {
                return [
                    "total" => $kfOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfOrderCHModel->hour)->format("H")
                ];
            })->values();

            //同比当天门店外卖订单时间段聚合订单数据
            $compareKfWmOrderCHModel = KfWaimaiOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["compareQueryStartDate"]}')")
            )->select([
                    raw('sum(originalPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfWaimaiOrderCHModel $kfWaimaiOrderCHModel) {
                return [
                    "total" => $kfWaimaiOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfWaimaiOrderCHModel->hour)->format("H")
                ];
            })->values();

            $list = collect($parsedCoords["xValues"])->merge(["24:00"])->map(function ($xValue) use (
                $kfOrderCHModel,
                $kfWmOrderCHModel
            ) {
                $intHour    = (int)(explode(":", $xValue)[0]);
                $orderSum   = $kfOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                $wmOrderSum = $kfWmOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                return [
                    "x"   => $xValue,
                    "val" => $orderSum + $wmOrderSum
                ];
            })->values();

            $comparedList = collect($parsedCoords["xValues"])->merge(["24:00"])->map(function ($xValue) use (
                $compareKfOrderCHModel,
                $compareKfWmOrderCHModel
            ) {
                $intHour    = (int)(explode(":", $xValue)[0]);
                $orderSum   = $compareKfOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                $wmOrderSum = $compareKfWmOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                return [
                    "x"   => $xValue,
                    "val" => $orderSum + $wmOrderSum
                ];
            })->values();

            $listSum         = attributeGet($list->last(), "val", 0);
            $comparedListSum = attributeGet($comparedList->last(), "val", 0);
        }


        return [
            "select"         => [
                "list" => $list->toArray(),
                "sum"  => (string)$listSum,
            ],
            "comparedSelect" => [
                "list" => $comparedList,
                "sum"  => (string)$comparedListSum
            ],
            "diff"           => (string)($listSum - $comparedListSum),
            "rate"           => $comparedListSum ? ((string)(round(bcdiv($listSum - $comparedListSum, $comparedListSum,
                        4),
                        2) * 100)) . "%" : "-"
        ];
    }

    /**
     * 营收情况 - 实收
     *
     * @param int $role
     * @param array $parsedCoords
     * @param int $regionSelectionType
     * @param string $region
     * @param string $regionValue
     * @return array[]
     * @throws ClientException
     */
    private static function revenueSituation_2(
        int $role,
        array $parsedCoords,
        int $regionSelectionType,
        string $region,
        string $regionValue
    ): array {
        if ($parsedCoords["groupType"] == "d") {
            if (
                $parsedCoords["queryEndDate"] == $parsedCoords["queryStartDate"]
                &&
                $parsedCoords["queryStartDate"] == Carbon::now()->format("Y-m-d")
            ) {
                //当天gmv取夸父收银
                $total              = KfOrderCHModel::buildHomeSearchQuery(
                    $role, $regionSelectionType, $region, $regionValue
                )->where(
                    "completeTime", ">=", Carbon::now()->startOfDay()->timestamp
                )->select([raw('sum(realPayPrice) as total')])->first();
                $businessCollection = collect([
                    [
                        "x"   => $parsedCoords["queryEndDate"],
                        "val" => bcdiv100($total['total'] ?? 0)
                    ]
                ]);
            } else {
                //选中日期 实收
                $businessCollection = GyDailyDeliveryReportCHModel::buildHomeSearchQuery(
                    $role, $regionSelectionType, $region
                )->where(
                    "date", ">=", $parsedCoords["queryStartDate"]
                )->where(
                    "date", "<=", $parsedCoords["queryEndDate"]
                )->groupBy(
                    "date"
                )->select(
                    ["date as x", raw("sum(actualAmountOfOrderReceived) as val")]
                )->get();
            }

            //选中日期同比 gmv
            $compareBusinessCollection = GyDailyDeliveryReportCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region
            )->where(
                "date", ">=", $parsedCoords["compareQueryStartDate"]
            )->where("date", "<=", $parsedCoords["compareQueryEndDate"]
            )->groupBy(
                "date"
            )->select(
                ["date as x", raw("sum(actualAmountOfOrderReceived) as val")]
            )->get();

            $list = collect($parsedCoords["xValues"])
                ->map(function ($xValue) use ($businessCollection) {
                    return [
                        "x"   => $xValue,
                        "val" => (string)(attributeGet(
                                $businessCollection->where("x", $xValue)->first(),
                                "val",
                                0
                            ) * 100)
                    ];
                })->values();

            $comparedList = collect($parsedCoords["xCompareValues"])
                ->map(function ($xValue) use ($compareBusinessCollection) {
                    return [
                        "x"   => $xValue,
                        "val" => (string)(attributeGet(
                                $compareBusinessCollection->where("x", $xValue)->first(),
                                "val",
                                0
                            ) * 100)
                    ];
                })->values();

            $listSum         = $list->pluck("val")->sum();
            $comparedListSum = $comparedList->pluck("val")->sum();
        } else {
            // 当天门店堂食订单时间段聚合订单实收数据
            $kfOrderCHModel = KfOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["queryStartDate"]}')")
            )->select([
                    raw('sum(realPayPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfOrderCHModel $kfOrderCHModel) {
                return [
                    "total" => $kfOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfOrderCHModel->hour)->format("H")
                ];
            })->values();

            // 当天门店外卖订单时间段聚合订单实收数据
            $kfWmOrderCHModel = KfWaimaiOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["queryStartDate"]}')")
            )->select([
                    raw('sum(payPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfWaimaiOrderCHModel $kfWaimaiOrderCHModel) {
                return [
                    "total" => $kfWaimaiOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfWaimaiOrderCHModel->hour)->format("H")
                ];
            })->values();

            //同比当天门店堂食订单时间段聚合订单数据
            $compareKfOrderCHModel = KfOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["compareQueryStartDate"]}')")
            )->select([
                    raw('sum(originalPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfOrderCHModel $kfOrderCHModel) {
                return [
                    "total" => $kfOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfOrderCHModel->hour)->format("H")
                ];
            })->values();

            //同比当天门店外卖订单时间段聚合订单数据
            $compareKfWmOrderCHModel = KfWaimaiOrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->where(raw('toDate(toDateTime(completeTime))'), raw("toDate('{$parsedCoords["compareQueryStartDate"]}')")
            )->select([
                    raw('sum(payPrice) AS total_original_price'),
                    raw('toStartOfHour(toDateTime(completeTime)) AS hour')
                ]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (KfWaimaiOrderCHModel $kfWaimaiOrderCHModel) {
                return [
                    "total" => $kfWaimaiOrderCHModel->total_original_price,
                    "hour"  => (int)Carbon::createFromDate($kfWaimaiOrderCHModel->hour)->format("H")
                ];
            })->values();

            $list = collect($parsedCoords["xValues"])->merge(["24:00"])->map(function ($xValue) use (
                $kfOrderCHModel,
                $kfWmOrderCHModel
            ) {
                $intHour    = (int)(explode(":", $xValue)[0]);
                $orderSum   = $kfOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                $wmOrderSum = $kfWmOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                return [
                    "x"   => $xValue,
                    "val" => $orderSum + $wmOrderSum
                ];
            })->values();

            $comparedList = collect($parsedCoords["xValues"])->merge(["24:00"])->map(function ($xValue) use (
                $compareKfOrderCHModel,
                $compareKfWmOrderCHModel
            ) {
                $intHour    = (int)(explode(":", $xValue)[0]);
                $orderSum   = $compareKfOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                $wmOrderSum = $compareKfWmOrderCHModel->where("hour", "<", $intHour)->pluck("total")->sum();
                return [
                    "x"   => $xValue,
                    "val" => $orderSum + $wmOrderSum
                ];
            })->values();

            $listSum         = attributeGet($list->last(), "val", 0);
            $comparedListSum = attributeGet($comparedList->last(), "val", 0);
        }


        return [
            "select"         => [
                "list" => $list->toArray(),
                "sum"  => (string)$listSum
            ],
            "comparedSelect" => [
                "list" => $comparedList,
                "sum"  => (string)$comparedListSum
            ],
            "diff"           => (string)($listSum - $comparedListSum),
            "rate"           => $comparedListSum ? ((string)(round(bcdiv($listSum - $comparedListSum, $comparedListSum,
                        4),
                        2) * 100)) . "%" : "-"
        ];

    }

    /**
     * 营收情况 - 实收
     *
     * @param int $role
     * @param array $parsedCoords
     * @param int $regionSelectionType
     * @param string $region
     * @param string $regionValue
     * @return array[]
     * @throws ClientException
     */
    private static function revenueSituation_3(
        int $role,
        array $parsedCoords,
        int $regionSelectionType,
        string $region,
        string $regionValue
    ): array {
        if ($parsedCoords["groupType"] == "d") {

//            if (
//                $parsedCoords["queryEndDate"] == $parsedCoords["queryStartDate"]
//                &&
//                $parsedCoords["queryStartDate"] == Carbon::now()->format("Y-m-d")
//            ) {
//                //当天订货数据取实时数据
//                $businessCollection = OrderCHModel::buildHomeSearchQuery(
//                    $role, $regionSelectionType, $region, $regionValue
//                )->as("mainOrder")->final()->join(function(JoinClause  $join){
//                    $join->table((new DeliveryNoteGoodsCHModel())->getTable())
//                         ->as("detail")
//                         ->on("mainOrder.id",'=','detail.new_order_id');
//                })->where("x", ">=", $parsedCoords["queryStartDate"]
//                )->where("x", "<=", $parsedCoords["queryEndDate"]
//                )->whereIn("payment_status", [2, 3]
//                )->where("delete_time", 0
//                )->groupBy("x"
//                )->orderByDesc("x"
//                )->select([raw("formatDateTime(toDate(pay_time), '%Y-%m-%d') as x"), raw("sum(single_sales_price*num) as val")]
//                )->get();
//            } else {
                //选中日期 实收
//                $businessCollection = GyDmDaySalesAnalyseCHModel::buildHomeSearchQuery(
//                    $role, $regionSelectionType, $region
//                )->where(
//                    "timeOfPayment", ">=", $parsedCoords["queryStartDate"]
//                )->where(
//                    "timeOfPayment", "<=", $parsedCoords["queryEndDate"]
//                )->groupBy(
//                    "timeOfPayment"
//                )->select(
//                    ["timeOfPayment as x", raw("sum(salesAmount) as val")]
//                )->get();
//            }

            //选中日期同比 gmv
//            $compareBusinessCollection = GyDmDaySalesAnalyseCHModel::buildHomeSearchQuery(
//                $role, $regionSelectionType, $region
//            )->where(
//                "timeOfPayment", ">=", $parsedCoords["compareQueryStartDate"]
//            )->where(
//                "timeOfPayment", "<=", $parsedCoords["compareQueryEndDate"]
//            )->groupBy(
//                "timeOfPayment"
//            )->select(
//                ["timeOfPayment as x", raw("sum(salesAmount) as val")]
//            )->get();

            $newOrdersTableName = (new NewOrdersModel())->getTable();
            $deliveryNoteGoodsModelTableName = (new DeliveryNoteGoodsModel())->getTable();

            $businessCollection = NewOrdersModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->join(
                $deliveryNoteGoodsModelTableName,
                function (\Illuminate\Database\Query\JoinClause $join) use (
                    $newOrdersTableName,
                    $deliveryNoteGoodsModelTableName
                ) {
                    $join->on("{$newOrdersTableName}.id", "=", "$deliveryNoteGoodsModelTableName.new_order_id");
                }
            )->where("pay_time", ">=", Carbon::createFromTimestamp(strtotime($parsedCoords["queryStartDate"]))->startOfDay()->timestamp
            )->where("pay_time", "<=", Carbon::createFromTimestamp(strtotime($parsedCoords["queryEndDate"]))->endOfDay()->timestamp
            )->whereIn("payment_status", [2, 3]
            )->where("{$newOrdersTableName}.delete_time", 0
            )->where("{$deliveryNoteGoodsModelTableName}.delete_time", 0
            )->groupBy("x"
            )->orderByDesc("x"
            )->select([
                DB::raw("FROM_UNIXTIME(pay_time, '%Y-%m-%d') as x"),
                    DB::raw("sum(single_sales_price*num) as val")
                ]
            )->get();


            //选中日期 gmv
//            $businessCollection = OrderCHModel::buildHomeSearchQuery(
//                $role, $regionSelectionType, $region, $regionValue
//            )->as("mainOrder")->final()->join(function(JoinClause  $join){
//                $join->table((new DeliveryNoteGoodsCHModel())->getTable())
//                     ->as("detail")
//                     ->on("mainOrder.id",'=','detail.new_order_id');
//            })->where("x", ">=", $parsedCoords["queryStartDate"]
//            )->where("x", "<=", $parsedCoords["queryEndDate"]
//            )->whereIn("payment_status", [2, 3]
//            )->where("mainOrder.delete_time", 0
//            )->where("detail.delete_time", 0
//            )->groupBy("x"
//            )->orderByDesc("x"
//            )->select([raw("formatDateTime(toDate(pay_time), '%Y-%m-%d') as x"), raw("sum(single_sales_price*num) as val")]
//            )->get();

            //选中日期同比 gmv
            $compareBusinessCollection = NewOrdersModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->join(
                $deliveryNoteGoodsModelTableName,
                function (\Illuminate\Database\Query\JoinClause $join) use (
                    $newOrdersTableName,
                    $deliveryNoteGoodsModelTableName
                ) {
                    $join->on("{$newOrdersTableName}.id", "=", "$deliveryNoteGoodsModelTableName.new_order_id");
                }
            )->where("pay_time", ">=", Carbon::createFromTimestamp(strtotime($parsedCoords["compareQueryStartDate"]))->startOfDay()->timestamp
            )->where("pay_time", "<=", Carbon::createFromTimestamp(strtotime($parsedCoords["compareQueryEndDate"]))->endOfDay()->timestamp
            )->whereIn("payment_status", [2, 3]
            )->where("{$newOrdersTableName}.delete_time", 0
            )->where("{$deliveryNoteGoodsModelTableName}.delete_time", 0
            )->groupBy("x"
            )->orderByDesc("x"
            )->select([
                    DB::raw("FROM_UNIXTIME(pay_time, '%Y-%m-%d') as x"),
                    DB::raw("sum(single_sales_price*num) as val")
                ]
            )->get();
            //选中日期同比 gmv
//            $compareBusinessCollection = OrderCHModel::buildHomeSearchQuery(
//                $role, $regionSelectionType, $region, $regionValue
//            )->as("mainOrder")->final()->join(function(JoinClause  $join){
//                $join->table((new DeliveryNoteGoodsCHModel())->getTable())
//                     ->as("detail")
//                     ->on("mainOrder.id",'=','detail.new_order_id');
//            })->where("x", ">=", $parsedCoords["compareQueryStartDate"]
//            )->where("x", "<=", $parsedCoords["compareQueryEndDate"]
//            )->whereIn("payment_status", [2, 3]
//            )->where("mainOrder.delete_time", 0
//            )->where("detail.delete_time", 0
//            )->groupBy("x"
//            )->orderByDesc("x"
//            )->select([raw("formatDateTime(toDate(pay_time), '%Y-%m-%d') as x"), raw("sum(single_sales_price*num) as val")]
//            )->get();

            $list = collect($parsedCoords["xValues"])
                ->map(function ($xValue) use ($businessCollection) {
                    return [
                        "x"   => $xValue,
                        "val" => (string)(attributeGet(
                                $businessCollection->where("x", $xValue)->first(),
                                "val",
                                0
                            ) * 100)
                    ];
                })->values();

            $comparedList = collect($parsedCoords["xCompareValues"])
                ->map(function ($xValue) use ($compareBusinessCollection) {
                    return [
                        "x"   => $xValue,
                        "val" => (string)(attributeGet(
                                $compareBusinessCollection->where("x", $xValue)->first(),
                                "val",
                                0
                            ) * 100)
                    ];
                })->values();
        } else {
            $kfOrderCHModel = OrderCHModel::buildHomeSearchQuery($role, $regionSelectionType, $region, $regionValue)
                                        ->as("mainOrder")->final()->join(function(JoinClause  $join){
                                            $join->table((new DeliveryNoteGoodsCHModel())->getTable())
                                                 ->as("detail")
                                                 ->on("mainOrder.id",'=','detail.new_order_id');
                                        })
                                          ->whereIn("payment_status", [2, 3])
                                          ->where("delete_time", 0)
                                          ->where(
                                              raw('toDate(toDateTime(pay_time))'),
                                              raw("toDate('{$parsedCoords["queryStartDate"]}')")
                                          )
                                          ->select([
                                              raw('sum(single_sales_price*num) AS totalPrice'),
                                              raw('toStartOfHour(toDateTime(pay_time)) AS hour')
                                          ])
                                          ->groupBy("hour")
                                          ->orderBy("hour")
                                          ->get()
                                          ->map(function (OrderCHModel $orderCHModel) {
                                              return [
                                                  "total" => $orderCHModel->totalPrice,
                                                  "hour"  => (int)Carbon::createFromDate($orderCHModel->hour)
                                                                        ->format("H")
                                              ];
                                          })->values();


            $compareKfOrderCHModel = OrderCHModel::buildHomeSearchQuery(
                $role, $regionSelectionType, $region, $regionValue
            )->as("mainOrder")->final()->join(function(JoinClause  $join){
                $join->table((new DeliveryNoteGoodsCHModel())->getTable())
                     ->as("detail")
                     ->on("mainOrder.id",'=','detail.new_order_id');
            })->whereIn(
                "payment_status", [2, 3]
            )->where(
                "delete_time", 0
            )->where(raw('toDate(toDateTime(pay_time))'), raw("toDate('{$parsedCoords["compareQueryStartDate"]}')")
            )->select([raw('sum(single_sales_price*num) AS totalPrice'), raw('toStartOfHour(toDateTime(pay_time)) AS hour')]
            )->groupBy("hour"
            )->orderBy("hour"
            )->get()->map(function (OrderCHModel $orderCHModel) {
                return [
                    "total" => $orderCHModel->totalPrice,
                    "hour"  => (int)Carbon::createFromDate($orderCHModel->hour)
                                          ->format("H")
                ];
            })->values();

            $list = collect($parsedCoords["xValues"])->merge(["24:00"])->map(function ($xValue) use ($kfOrderCHModel) {
                return [
                    "x"   => $xValue,
                    "val" => $kfOrderCHModel->where("hour", "<", (int)(explode(":", $xValue)[0]))
                                            ->pluck("total")
                                            ->sum()
                ];
            })->values();


            $comparedList = collect($parsedCoords["xValues"])->merge(["24:00"])->map(function ($xValue) use (
                $compareKfOrderCHModel
            ) {
                return [
                    "x"   => $xValue,
                    "val" => $compareKfOrderCHModel->where("hour", "<", (int)(explode(":", $xValue)[0]))
                                                   ->pluck("total")
                                                   ->sum()
                ];
            })->values();
        }

        $listSum         = $list->pluck("val")->sum();
        $comparedListSum = $comparedList->pluck("val")->sum();
        return [
            "select"         => [
                "list" => $list->toArray(),
                "sum"  => (string)$listSum
            ],
            "comparedSelect" => [
                "list" => $comparedList,
                "sum"  => (string)$comparedListSum
            ],
            "diff"           => (string)($listSum - $comparedListSum),
            "rate"           => $comparedListSum ? ((string)(round(bcdiv($listSum - $comparedListSum,
                        $comparedListSum, 4),
                        2) * 100)) . "%" : "-"
        ];
    }

    /**
     * kms - 首页数据展示 - 门店构成&本月新开&本月新签&本月选址&商场渗透率&门店筹备
     *
     * @return string[]
     * @throws ClientException
     */
    public static function baseData(object $params): array
    {
        if ($params->role == UserRoleService::ROLE_BASE_SUPERVISOR) {
            throw new KfHttpResponseException(HomeError::CURRENT_ROLE_HAS_NO_PERMISSION_ACCESS_CURRENT_MODULE);
        }

        $dtNow = Carbon::now();

        //构建基础查询条件query
        $gyShopSignCHModelBaseQuery                    = GyShopSignCHModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region
        );
        $gyShopCityConsumptionOpeningsCHModelBaseQuery = GyShopCityConsumptionOpeningsCHModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region
        );

        $gyCloseShopCHModelBaseQuery = GyCloseShopCHModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region
        );

        $gyPreparatoryOverviewCHModelBaseQuery = GyPreparatoryOverviewCHModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region
        );

        $shopBusinessBaseQuery = GuanyuanSyncShopBusinessModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region
        );

        //todo 本月新签
        $monthSigned = [
            "monthSignedCount"    => (string)(clone $gyShopSignCHModelBaseQuery)->where(
                "paybackTime", ">=", $dtNow->copy()->startOfMonth()->format("Y-m-d")
            )->count(),
            "threadQuantityCount" => (string)(clone $gyShopCityConsumptionOpeningsCHModelBaseQuery)
                    ->where("date", $dtNow->copy()->subDay()->format("Y-m-d"))
                    ->select([raw('sum(threadQuantity) as threadQuantityCount')])
                    ->first()
                    ->toArray()["threadQuantityCount"] ?? 0,
            "classify"            => [
                "fissionCount"            => (string)(clone $gyShopSignCHModelBaseQuery)->where(
                    "paybackTime", ">=", Carbon::now()->startOfMonth()->format("Y-m-d")
                )->where("customerSource", "老店裂变")->count(),
                "provinceInvestmentCount" => (string)(clone $gyShopSignCHModelBaseQuery)->where(
                    "paybackTime", ">=", Carbon::now()->startOfMonth()->format("Y-m-d")
                )->where("customerSource", "省区拉新")->count()
            ]
        ];


        //todo 本月新开
        $monthNew = [
            "targetCount"  => $targetCount = (string)(clone $gyPreparatoryOverviewCHModelBaseQuery)
                    ->where("month",
                        $dtNow->copy()->startOfMonth()
                              ->format("Y-m-d"))
                    ->select([raw('sum(newTarget) as targetCount')])
                    ->first()
                    ->toArray()["targetCount"] ?? 0,
            "openedCount"  => $openedCount = (string)(clone $gyPreparatoryOverviewCHModelBaseQuery)
                    ->where("month",
                        $dtNow->copy()->startOfMonth()
                              ->format("Y-m-d"))
                    ->select([raw('sum(actualNewOpening) as openedCount')])
                    ->first()
                    ->toArray()["openedCount"] ?? 0,
            "residueCount" => (string)($targetCount - $openedCount)
        ];

        //todo 门店构成
        $storeComposition = (clone $gyCloseShopCHModelBaseQuery)
            ->whereIn("status", [
                "筹备中",
                "选址中",
                "正常营业",
                "暂停营业"
            ])
            ->groupBy("status")
            ->select(["status", raw('count(*) as count')])
            ->get();

        $gyCloseShopCode = (clone $gyCloseShopCHModelBaseQuery)
            ->where("status", "正常营业")
            ->get()
            ->pluck("berthNumber")
            ->map(function($v){
                return (int)$v;
            })
            ->toArray();

        $yesterday = date('Y-m-d', strtotime('-1 day'));
        $businessShopCodes = $shopBusinessBaseQuery->where('date', $yesterday)
                                                   ->pluck('code')
                                                   ->toArray();// 昨天有数据的门店

        $signOrderTable   = (new OpenShopSignOrderModel())->getTable();
        $mainProcessTable = (new OpenShopMainProcessModel())->getTable();
        $normalShopCount = OpenShopSignOrderModel::query()
                                                 ->leftJoin(
                                                     $mainProcessTable,
                                                     "$mainProcessTable.id",
                                                     "$signOrderTable.mainProcessId"
                                                 )->whereIn("$signOrderTable.status", [
                                                        SignOrderEnum::ORDER_STATUS_OK,
                                                        SignOrderEnum::ORDER_STATUS_COMPLETE
                                                    ])
                                                 ->whereIn("$signOrderTable.ShopCode",
                                                     array_unique(array_merge($gyCloseShopCode, $businessShopCodes)))
                                                 ->whereIn("$mainProcessTable.nowStepStatus", [
                                                     MissionTemplateEnum::STEP_STATUS_18,
                                                     MissionTemplateEnum::STEP_STATUS_999
                                                 ])
                                                 ->groupBy("$signOrderTable.shopCode")
                                                 ->select(["$signOrderTable.shopCode"])
                                                 ->get()->count();

        $gyStoreCompositionSum = $storeComposition->pluck("count")->sum();
        $storeCompositionSum   = $gyStoreCompositionSum + $normalShopCount -
            attributeGet($storeComposition->where("status", "正常营业")->first(), "count", 0);
        $storeComposition    = collect([
            "正常营业",
            "暂停营业",
            "筹备中",
            "选址中"
        ])->map(function ($status) use ($storeComposition, $storeCompositionSum, $normalShopCount) {
            if($status == "正常营业"){
                $count = $normalShopCount;
            }else{
                $count = attributeGet($storeComposition->where("status", $status)->first(), "count", 0);
            }
            return [
                "status" => $status,
                "count"  => (string)$count,
                "rate"   => $storeCompositionSum ? ((string)(round(bcdiv($count, $storeCompositionSum, 4),
                            3) * 100)) . "%" : "0"
            ];
        })->values()->toArray();

        //todo 商场渗透率
        $siteLocationMallModel = SiteLocationMallModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region, $params->regionValue
        )->groupBy(
            ["grade", "settle"]
        )->select(["settle", "grade", DB::raw('count(settle) as count')])->get();

        $marketPenetration = collect(SiteLocationMallModel::SITE_MALL_GRADE_MAPPING)
            ->map(function ($desc, $grade) use ($siteLocationMallModel) {
                $settleYes = attributeGet(
                    $siteLocationMallModel->where("grade", $grade)->where("settle", 1)->first(),
                    "count",
                    0
                );
                $total     = $siteLocationMallModel->where("grade", $grade)->pluck("count")->sum();
                return [
                    "desc"      => (string)$desc,
                    "grade"     => (string)$grade,
                    "count"     => (string)$total,
                    "settleYes" => (string)$settleYes,
                    "settleNo"  => (string)attributeGet(
                        $siteLocationMallModel->where("grade", $grade)->where("settle", 0)->first(),
                        "count",
                        0
                    ),
                    "rate"      => $total ? ((string)(round(bcdiv($settleYes, $total, 4),
                                2) * 100)) . "%" : "-"
                ];
            })->values()->toArray();

        //todo 获取本月选址
        $monthSiteSelection = [
            //本月选址中
            "inHandCount"  => (string)(clone $gyCloseShopCHModelBaseQuery)
                ->where("status", "选址中")
                ->count(),
//                (function (object $params) {
//                $mainProcessOrderNos = OpenShopMainProcessModel::query()
//                                                               ->whereIn("nowStepStatus", [3, 4, 5])
//                                                               ->pluck("orderNo")
//                                                               ->toArray();
//
//                $shopAddressOrderNos = OpenShopAddressModel::buildHomeSearchQuery(
//                    $params->regionSelectionType, $params->region, $params->regionValue
//                )->pluck("orderNo")->toArray();
//
//                if ($mainProcessOrderNos && $shopAddressOrderNos && $inOrderNos = array_intersect($mainProcessOrderNos,
//                        $shopAddressOrderNos)) {
//                    return (string)OpenShopSignOrderModel::query()
//                                                         ->where('orderNo', $inOrderNos)
//                                                         ->where("status", SignOrderEnum::ORDER_STATUS_OK)
//                                                         ->count();
//                }
//                return "0";
//            })($params),

            //本月商家确认选址数量
            "confirmCount" => (string)(clone $gyCloseShopCHModelBaseQuery)
                ->where("confirmSiteLocationTime", ">=", Carbon::now()->startOfMonth()->format("Y-m-d"))
                ->count(),
//                (string)OpenShopSiteMissionModel::buildHomeSearchQuery(
//                $params->regionSelectionType, $params->region, $params->regionValue
//            )->where("stepStatus", MissionTemplateEnum::STEP_STATUS_5
//            )->where("status", SiteMissionEnum::STATUS_2
//            )->where("completeAt", ">=", $dtNow->copy()->startOfMonth()->timestamp
//            )->where("completeAt", "<", $dtNow->copy()->addMonth()->startOfMonth()->timestamp
//            )->count(),

            //选址活跃
            "activeCount"  => (string)(clone $gyCloseShopCHModelBaseQuery)
                ->where("status", "选址中")
                ->where("secondaryState", "活跃客户")
                ->count(),
//                (string)OpenShopOrderTagsMappingModel::query()->whereIn("id",
//        OpenShopOrderTagsMappingModel::query()->select(DB::raw("max(id) as maxId"))
//                                     ->from((new OpenShopOrderTagsMappingModel())->getTable())
//                                     ->groupBy("orderNo")->get()->pluck("maxId")->toArray())->where(
//        "tagId", OpenShopOrderTagsMappingModel::TAG_TYPE_14
//    )->count(),

            //选址沉默
            "silenceCount" => (string)(clone $gyCloseShopCHModelBaseQuery)
                ->where("status", "选址中")
                ->where("secondaryState", "沉默客户")
                ->count(),
//                (string)OpenShopOrderTagsMappingModel::query()->whereIn("id",
//        OpenShopOrderTagsMappingModel::query()->select(DB::raw("max(id) as maxId"))
//                                     ->from((new OpenShopOrderTagsMappingModel())->getTable())
//                                     ->groupBy("orderNo")->get()->pluck("maxId")->toArray()
//    )->whereIn(
//        "tagId", [OpenShopOrderTagsMappingModel::TAG_TYPE_16, OpenShopOrderTagsMappingModel::TAG_TYPE_18]
//    )->count(),
        ];


        //todo 门店凑备
        $shopPreparation = [
            "normalCount"    => (string)(clone $gyCloseShopCHModelBaseQuery)->where("secondaryState", "筹备正常")->count(),
            "exceptionCount" => (string)(clone $gyCloseShopCHModelBaseQuery)->where("secondaryState", "筹备异常")->count(),
            "monthOpenCount" => (string)(clone $gyCloseShopCHModelBaseQuery)
                ->where("status", "筹备中")
                ->where(
                    "estimatedOpeningTime", ">=", Carbon::now()->format("Y-m-d")
                )
                ->where(
                    "estimatedOpeningTime", "<=", Carbon::now()->endOfMonth()->format("Y-m-d")
                )
                ->count()
        ];

        return [
            "storeCompositionTotal" => $gyStoreCompositionSum,
            "storeComposition"      => $storeComposition,
            "monthNew"              => $monthNew,
            "monthSigned"           => $monthSigned,
            "monthSiteSelection"    => $monthSiteSelection,
            "marketPenetration"     => $marketPenetration,
            "shopPreparation"       => $shopPreparation
        ];
    }

    /**
     * 新开日历
     *
     * @param object $params
     * @return array
     * @throws ClientException
     */
    public static function newlyOpenedStore(object $params): array
    {
        $openedShopCodes = GyCloseShopCHModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region
        )->where(
            "status", "正常营业"
        )->where(
            raw("formatDateTime(toDate(openingDate), '%Y-%m')"), "=", $params->date
        )->get()->map(function (GyCloseShopCHModel $gyCloseShopCHModel) {
            $gyCloseShopCHModel->berthNumber = ltrim($gyCloseShopCHModel->berthNumber, "0");
            return $gyCloseShopCHModel;
        })->pluck("berthNumber")->values()->toArray();

        $noOpenedShopCodes = GyCloseShopCHModel::buildHomeSearchQuery(
            $params->regionSelectionType, $params->region
        )->where(
            "status", "筹备中"
        )->where(
            raw("formatDateTime(toDate(estimatedOpeningTime), '%Y-%m')"), $params->date
        )->get()->map(function (GyCloseShopCHModel $gyCloseShopCHModel) {
            $gyCloseShopCHModel->berthNumber = ltrim($gyCloseShopCHModel->berthNumber, "0");
            return $gyCloseShopCHModel;
        })->pluck("berthNumber")->values()->toArray();

        $shopCodes = array_unique(array_merge($openedShopCodes, $noOpenedShopCodes));

        $shopCodesCollection = GyCloseShopCHModel::buildHomeSearchQuery($params->regionSelectionType, $params->region)
                                                 ->where(
                                                     function ($query) use ($params) {
                                                         $query
                                                             ->where(raw("formatDateTime(toDate(estimatedOpeningTime), '%Y-%m')"),
                                                                 $params->date)
                                                             ->where(raw("formatDateTime(toDate(openingDate), '%Y-%m')"),
                                                                 "=", $params->date, "OR");
                                                     }
                                                 )->get()
                                                 ->map(function (GyCloseShopCHModel $gyCloseShopCHModel) {
                                                     $gyCloseShopCHModel->berthNumber = ltrim($gyCloseShopCHModel->berthNumber,
                                                         "0");
                                                     return $gyCloseShopCHModel;
                                                 });


        $list = ShopModel::query()->whereIn("shopCode", $shopCodes)
                         ->with([
                             "signOrderRel" => function ($query) {
                                 $query->with(["lastSiteMissionsRel", "startBusinessRel"]);
                             }
                         ])
                         ->get()
                         ->map(function (ShopModel $shopModel) use ($shopCodesCollection) {
                             $lastStepStatus = attributeGet($shopModel,
                                 "signOrderRel.lastSiteMissionsRel.stepStatus", 0);
                             $lastStatus     = attributeGet($shopModel,
                                 "signOrderRel.lastSiteMissionsRel.status", 0);

                             if ($lastStepStatus == UserOrderEnum::STEP_FORMAT_18 && $lastStatus == SiteMissionEnum::STATUS_2) {
                                 $missionName = "已开业";
                             } else {
                                 $missionName = attributeGet($shopModel,
                                     "signOrderRel.lastSiteMissionsRel.missionName", "-");
                             }

                             $row      = $shopCodesCollection->where("berthNumber", $shopModel->shopCode)->first();
                             $sortDate = 0;
                             if (attributeGet($row, "openingDate", null)) {
                                 $estimatedOpeningDate = date("m月d日",
                                     strtotime(attributeGet($row, "openingDate", null)));
                                 $sortDate             = date("Ymd",
                                     strtotime(attributeGet($row, "openingDate", null)));
                             } else {
                                 $estimatedOpeningDate = date("m月d日",
                                     strtotime(attributeGet($row, "estimatedOpeningTime", null)));
                                 $sortDate             = date("Ymd",
                                     strtotime(attributeGet($row, "estimatedOpeningTime", null)));
                             }

                             return [
                                 "orderNo"              => attributeGet($shopModel, "signOrderRel.orderNo", "-"),
                                 "name"                 => $shopModel->name,
                                 "shopCode"             => $shopModel->shopCode,
                                 "estimatedOpeningDate" => $estimatedOpeningDate,
                                 "missionName"          => $missionName,
                                 "sortDate"             => (int)$sortDate
                             ];
                         })
                         ->sortBy("sortDate")
                         ->values()
                         ->toArray();

        return [
            "shopList" => $list
        ];
    }

    /**
     * 首页门店自检模块数据
     *
     * @param object $params
     * @return array
     */
    public static function shopSelfCheckGroup(object $params): array
    {
        $baseQuery = CruiseCheckSelfDetailModel::buildHomeSearchQuery(
            $params->role,
            attributeGet($params, "regionSelectionType", -1),
            attributeGet($params, "region", ""),
            attributeGet($params, "regionValue", "")
        )->where(
            "templateType", CruiseTemplateModel::TYPE_8
        )->where(
            "cruiseOrderId", ">", 0
        );

        $carbonNow = Carbon::now();
        $clientFinishStatus = [
            CruiseCheckSelfDetailModel::STATUS_10,
            CruiseCheckSelfDetailModel::STATUS_9,
            CruiseCheckSelfDetailModel::STATUS_4
        ];

        // 今日开档
        $groupTodayOpen = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_OPEN
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfDay()->timestamp, $carbonNow->clone()->endOfDay()->timestamp]
        )->whereIn(
            "status", $clientFinishStatus
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        $groupTodayOpenTotal = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_OPEN
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfDay()->timestamp, $carbonNow->clone()->endOfDay()->timestamp]
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        // 今日闭档
        $groupTodayClose = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_CLOSE
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfDay()->timestamp, $carbonNow->clone()->endOfDay()->timestamp]
        )->whereIn(
            "status", $clientFinishStatus
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        $groupTodayCloseTotal = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_CLOSE
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfDay()->timestamp, $carbonNow->clone()->endOfDay()->timestamp]
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        // 周检
        $groupWeek = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_WEEK
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfWeek()->timestamp, $carbonNow->clone()->endOfWeek()->timestamp]
        )->whereIn(
            "status", $clientFinishStatus
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        $groupWeekTotal = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_WEEK
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfWeek()->timestamp, $carbonNow->clone()->endOfWeek()->timestamp]
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        // 月检
        $groupMonth = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_MONTH
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfMonth()->timestamp, $carbonNow->clone()->endOfMonth()->timestamp]
        )->whereIn(
            "status", $clientFinishStatus
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        $groupMonthTotal = (clone $baseQuery)->where(
            "sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_MONTH
        )->whereBetween(
            "createdAt", [$carbonNow->clone()->startOfMonth()->timestamp, $carbonNow->clone()->endOfMonth()->timestamp]
        )->select([DB::raw('count(distinct shopId) as total')])->first()->total;

        $todayReviewed = (clone $baseQuery)->whereBetween(
            "finishTime", [$carbonNow->clone()->startOfDay()->timestamp, $carbonNow->clone()->endOfDay()->timestamp]
        )->whereIn(
            "status", [CruiseCheckSelfDetailModel::STATUS_10, CruiseCheckSelfDetailModel::STATUS_9]
        )->get();

        $weekReviewed = (clone $baseQuery)->whereBetween(
            "finishTime", [$carbonNow->clone()->startOfWeek()->timestamp, $carbonNow->clone()->endOfWeek()->timestamp]
        )->whereIn(
            "status", [CruiseCheckSelfDetailModel::STATUS_10, CruiseCheckSelfDetailModel::STATUS_9]
        )->get();

        $weekStartTime  = Carbon::now()->endOfWeek()->subDay()->startOfDay()->timestamp;
        $monthStartTime = Carbon::now()->endOfMonth()->subDays(4)->startOfDay()->timestamp;
        return [
            "groupStatusData"   => [
                "groupTodayOpen"  => "{$groupTodayOpen}/{$groupTodayOpenTotal}",
                "groupTodayClose" => "{$groupTodayClose}/{$groupTodayCloseTotal}",
                "groupWeek"       => "{$groupWeek}/{$groupWeekTotal}",
                "groupMonth"      => time() > $monthStartTime ? "{$groupMonth}/{$groupMonthTotal}" : "未开始",
//                "groupWeek"       => "{$groupWeek}/{$groupWeekTotal}",
//                "groupMonth"      => "{$groupMonth}/{$groupMonthTotal}",
            ],
            "groupReviewedData" => [
                "todayReviewed" => [
                    "shopCount"   => $todayReviewed->pluck("shopId")->unique()->count(),
                    "reportCount" => $todayReviewed->count(),
                ],
                "weekReviewed"  => [
                    "shopCount"   => $weekReviewed->pluck("shopId")->unique()->count(),
                    "reportCount" => $weekReviewed->count(),
                ]
            ]
        ];
    }
}
